package com.xc.hotelmgr.datahandlermt.service.mt.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xc.hotelmgr.datahandlermt.expection.MTReqException;
import com.xc.hotelmgr.datahandlermt.pojo.mq.HtlGroupDto;
import com.xc.hotelmgr.datahandlermt.pojo.mq.TaskHotelList;
import com.xc.hotelmgr.datahandlermt.pojo.mybatis.*;
import com.xc.hotelmgr.datahandlermt.pojo.request.BreakfastCal;
import com.xc.hotelmgr.datahandlermt.sdk.FxBaseApiRequest;
import com.xc.hotelmgr.datahandlermt.sdk.MtClient;
import com.xc.hotelmgr.datahandlermt.service.mt.HtInfoService;
import com.xc.hotelmgr.datahandlermt.service.mybatis.*;
import com.xc.hotelmgr.datahandlermt.utils.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class HtInfoServiceImpl implements HtInfoService {

    private final HtPhysicalRoomService htPhysicalRoomService;

    private final HtChanelPhysicalRoomService htChanelPhysicalRoomService;

    private final HtLogicRoomService htLogicRoomService;

    private final HtHotelinfoService htHotelinfoService;

    private final HtDailyroomService htDailyroomService;

    private final HtChanelHotelinfoService htChanelHotelinfoService;

    private final SendMessageMgr sendMessageMgr;

    private final OpTaskStatusService opTaskStatusService;

    private final SaveErrId saveErrId;

    private final OpTaskDetailService opTaskDetailService;

    private final OpHtlGroupService opHtlGroupService;

    private final DtStoreService dtStoreService;

    /**
     * 获取酒店id
     */
    @Async
    @Override
    public void getHtId(Long taskIds) {
        String taskName = "全量酒店拉取";
        OpTaskStatus opTaskStatus = new OpTaskStatus();
        opTaskStatus.setArchive(0);
        opTaskStatus.setTaskCode("ALLHOTEL");
        opTaskStatus.setStatus(0);
        opTaskStatus.setCompAmount(0);
        opTaskStatus.setExcuTime(new Date());

        if (taskIds>0){
            taskName = "异常酒店拉取";
            opTaskStatus.setTaskName(taskName);
            List<OpTaskDetail> opTaskDetailList = opTaskDetailService.listAllTaskId(taskIds);
            opTaskDetailService.deleteAll(taskIds);
            int listSize = opTaskDetailList.size();
            //完成数
            opTaskStatus.setCompPercent(0);
            //总数
            opTaskStatus.setCompAmount(listSize);
            opTaskStatusService.insertIgnoreNull(opTaskStatus);
            Long taskId = opTaskStatus.getId();
            int index = 5;
            for (int i = 0; i < listSize; i += index) {
                if (i + index > listSize) {
                    index = listSize - i;
                }

                List<OpTaskDetail> newList = opTaskDetailList.subList(i, i + index);
                List<Long> hotelIdList = new ArrayList<>();
                for (OpTaskDetail hotelOpTaskDetail : newList) {
                    Long hId = hotelOpTaskDetail.getHotelId();
                    hotelIdList.add(hId);
                }
                if (!hotelIdList.isEmpty()){
                    //发送消息
                    TaskHotelList taskHotelList = new TaskHotelList();
                    taskHotelList.setTaskId(taskId);
                    taskHotelList.setHotelList(hotelIdList);
                    // 区分全量拉取与分组拉取标志
                    taskHotelList.setIsGroup(false);
                    sendMessageMgr.sendMessage(MqType.HTLIDLIST, taskHotelList, "");
                }
            }
            //结束标志
            List<Long> maxIdList = new ArrayList<>();
            TaskHotelList taskHotelList = new TaskHotelList();
            taskHotelList.setTaskId(taskId);
            taskHotelList.setHotelList(maxIdList);
            sendMessageMgr.sendMessage(MqType.HTLIDLIST,taskHotelList, "");
        }
        //全量酒店拉取
        else {
            opTaskStatus.setTaskName(taskName);
            opTaskStatusService.insertIgnoreNull(opTaskStatus);
            Long taskId = opTaskStatus.getId();

            JSONObject reqData = new JSONObject();
            int maxId = 0;
            reqData.put("maxId", maxId);
            reqData.put("pageSize", 1000);
            while (true) {
                FxBaseApiRequest fxBaseApiRequest = new FxBaseApiRequest();
                MtClient mtClient = new MtClient();
                fxBaseApiRequest.setData(reqData.toJSONString());
                fxBaseApiRequest.setMethod("hotel.poi.list");
                String mtResult = mtClient.post(fxBaseApiRequest);
                JSONObject mtResultJson = JSONObject.parseObject(mtResult);
                JSONObject result = (JSONObject) mtResultJson.get("result");
                JSONArray hotelIds = result.getJSONArray("hotelIds");//获取酒店id列表
                int listSize = hotelIds.size();
                int index = 5;
                for (int i = 0; i < listSize; i += index) {
                    if (i + index > listSize) {
                        index = listSize - i;
                    }
                    List newList = hotelIds.subList(i, i + index);

                    List<Long> hotelIdList = new ArrayList<>();
                    for (Object hotelId : newList) {
                        long hId = Long.parseLong(hotelId.toString());
                        hotelIdList.add(hId);
                    }
                    if (!hotelIdList.isEmpty()){
                        //发送消息
                        TaskHotelList taskHotelList = new TaskHotelList();
                        taskHotelList.setTaskId((long) taskId);
                        taskHotelList.setHotelList(hotelIdList);
                        // 区分全量拉取与分组拉取标志
                        taskHotelList.setIsGroup(false);
                        sendMessageMgr.sendMessage(MqType.HTLIDLISTALL, taskHotelList, "");
                    }

                }
                maxId = result.getInteger("maxId");
                log.info("maxId"+":"+maxId);
                reqData.put("maxId", maxId);
                /**判断条件为-1时程序停止*/
                if (maxId == -1) {
                    //将消息停止存消息队列
                    List<Long> maxIdList = new ArrayList<>();
                    TaskHotelList taskHotelList = new TaskHotelList();
                    taskHotelList.setTaskId(taskId);
                    taskHotelList.setHotelList(maxIdList);
                    sendMessageMgr.sendMessage(MqType.HTLIDLISTALL,taskHotelList, "");
                    break;
                }
            }
        }
        log.info("酒店id获取成功");
    }

    /**
     * 一键获取酒店所有信息
     */
    @Override
    public void getHtDetail(TaskHotelList taskHotelList) {
         getHtInfo(taskHotelList);
         getHtRooms(taskHotelList);
         getGoods(taskHotelList);
    }

    @Override
    public void getHtGroup(HtlGroupDto htlGroupDto) {
        List<OpDtStoreGroup> opDtStoreGroups = opHtlGroupService.getByGroup(htlGroupDto);
        //分组下没有酒店
        if(opDtStoreGroups.size() <= 0){
            return;
        }
        DtStore dtStore = dtStoreService.getById(htlGroupDto.getStoreId());
        String taskName = "分组酒店拉取【" + opDtStoreGroups.get(0).getGroupName() + "】";
        OpTaskStatus opTaskStatus = new OpTaskStatus();
        opTaskStatus.setArchive(0);
        opTaskStatus.setTaskCode("ALLHOTEL");
        opTaskStatus.setStatus(0);
        //完成数
        opTaskStatus.setCompPercent(0);
        //总数
        opTaskStatus.setCompAmount(opDtStoreGroups.size());
        opTaskStatus.setExcuTime(new Date());
        opTaskStatus.setTaskName(taskName);
        opTaskStatus.setStorId(htlGroupDto.getStoreId());
        opTaskStatus.setDtId(dtStore.getDtId());
        opTaskStatusService.insertIgnoreNull(opTaskStatus);
        Long taskId = opTaskStatus.getId();
        for (OpDtStoreGroup opDtStoreGroup : opDtStoreGroups) {
            List<Long> hotelIdList = new ArrayList<>();
            Long hId = opDtStoreGroup.getHotelId();
            hotelIdList.add(hId);
            //发送消息
            TaskHotelList taskHotelList = new TaskHotelList();
            taskHotelList.setTaskId(taskId);
            taskHotelList.setHotelList(hotelIdList);
            taskHotelList.setStoreId(htlGroupDto.getStoreId());
            taskHotelList.setGroupId(htlGroupDto.getGroupId());
            taskHotelList.setAppKey(opDtStoreGroup.getAppKey());
            taskHotelList.setSecret(opDtStoreGroup.getSecret());
            taskHotelList.setSessionKey(opDtStoreGroup.getSessionKey());
            taskHotelList.setIsGroup(true);
            sendMessageMgr.sendMessage(MqType.HTLIDLIST, taskHotelList, "");
        }
        List<Long> endIdList = new ArrayList<>();
        Integer StoreId = htlGroupDto.getStoreId();
        TaskHotelList taskHotelList = new TaskHotelList();
        taskHotelList.setTaskId(taskId);
        taskHotelList.setStoreId(StoreId);
        taskHotelList.setHotelList(endIdList);
        taskHotelList.setGroupId(htlGroupDto.getGroupId());
        sendMessageMgr.sendMessage(MqType.HTLIDLIST, taskHotelList, "");
    }

    @Override
    public void moveHtId(TaskHotelList taskHotelList) {
        //移动消息队列里的酒店id
        sendMessageMgr.sendMessage(MqType.HTLIDLIST, taskHotelList, "");
    }
    /**
     * 获取酒店信息
     */
    @Override
    public boolean getHtInfo(TaskHotelList taskHotelList) {
        FxBaseApiRequest fxBaseApiRequest = new FxBaseApiRequest();
        MtClient mtClient = new MtClient();

        Long taskId = taskHotelList.getTaskId();
        List<Long> mtCodes = taskHotelList.getHotelList();
        //请求美团数据，mysql取出酒店id请求美团酒店数据，一次查询20个酒店
        JSONObject reqData = new JSONObject();
        reqData.put("hotelIds", mtCodes);
        reqData.put("strategy", 3);
        fxBaseApiRequest.setData(reqData.toJSONString());
        fxBaseApiRequest.setMethod("hotel.detail");
        String mtResult = "";
        try {
            mtResult = mtClient.post(fxBaseApiRequest);
        }catch (Exception ex){
            throw  new MTReqException(ex.toString());
        }
        //对美团返回数据进行解析，返回结果是json字符串，包含20个酒店的物理房型信息
        JSONObject mtResultJson = JSONObject.parseObject(mtResult);
        int code = mtResultJson.getInteger("code");
        String message = mtResultJson.getString("message");
        if (code == 0) {
            JSONObject htResult = mtResultJson.getJSONObject("result");
            JSONArray hotelDetails = htResult.getJSONArray("hotelDetails");
            if (hotelDetails.isEmpty()) {
                List<HtHotelinfo> hotelinfos = htHotelinfoService.getByHotelCodes(mtCodes);
                hotelinfos = hotelinfos.stream().map((item)->{
                    item.setStatus(-2);
                    return item;
                }).collect(Collectors.toList());
                htHotelinfoService.updateBatchById(hotelinfos);
                saveErrId.saveIDList(mtCodes,taskId,"美团信息：酒店已经在美团下架");
                return false;
            }

            // 批量更新列表
            List<HtHotelinfo> hotelList = new ArrayList<>();
            List<HtChanelHotelinfo> chanelHotelList = new ArrayList<>();

            for (Object hotelDetail : hotelDetails) {
                //实体类
                HtHotelinfo htHotelinfo = new HtHotelinfo();
                HtChanelHotelinfo htChanelHotelinfo = new HtChanelHotelinfo();

                //酒店基本信息
                JSONObject htDetail = (JSONObject) JSONObject.toJSON(hotelDetail);
                JSONObject baseInfo = htDetail.getJSONObject("baseInfo");
                String hotelId = baseInfo.getString("hotelId");
                String pointName = baseInfo.getString("pointName");
                String address = baseInfo.getString("address");
                String cityLocationIdStr = baseInfo.getString("cityLocationId");
                String locationIdStr = baseInfo.getString("locationId");
                //String brandId = baseInfo.getString("brandId");
                String phone = baseInfo.getString("phone");
                //String info = baseInfo.getString("info");
                String longitude = baseInfo.getString("longitude");
                String latitude = baseInfo.getString("latitude");
                Integer closeStatus = baseInfo.getInteger("closeStatus");
                //如果酒店状态不等于0，则状态为下架
                if(!closeStatus.equals(0)) {
                    closeStatus = -2;
                }
                int brandId = baseInfo.getInteger("brandId");
                String brandName = baseInfo.getString("brandName");
                int cityLocationId = Integer.parseInt(cityLocationIdStr);

                //判断城市编码，逐级赋值
                if (locationIdStr == null) {
                    htHotelinfo.setDistrict(cityLocationId);
                    htChanelHotelinfo.setDistrict(cityLocationId);
                } else {
                    int locationId = Integer.parseInt(locationIdStr);
                    htHotelinfo.setCounty(locationId);
                    htChanelHotelinfo.setCounty(locationId);
                    htHotelinfo.setDistrict(locationId);
                    htChanelHotelinfo.setDistrict(locationId);
                }

                //物理酒店
                Long hotelIdLong = Long.parseLong(hotelId);
                htHotelinfo.setHotelCode(hotelIdLong);
                htHotelinfo.setId(hotelIdLong);
                htHotelinfo.setHotelName(pointName);
                htHotelinfo.setAddress(address);
                htHotelinfo.setBrand(brandId);
                htHotelinfo.setBrandName(brandName);
                htHotelinfo.setPhone(phone);
                //htHotelinfo.setHotelInfo(info);
                htHotelinfo.setAxesX(longitude);
                htHotelinfo.setAxesY(latitude);
                htHotelinfo.setStatus(closeStatus);
//                htHotelinfo.setPictureurl(frontImage);
                htHotelinfo.setManualVerify(0);
                htHotelinfo.setCity(cityLocationId);
//                //渠道物理酒店
//                htChanelHotelinfo.setHotelCode(hotelIdLong);
//                htChanelHotelinfo.setId(hotelIdLong);
//                htChanelHotelinfo.setChanelHotelCode(hotelIdLong);
//                htChanelHotelinfo.setHotelName(pointName);
//                htChanelHotelinfo.setAddress(address);
//                htChanelHotelinfo.setBrand(brandId);
//                htChanelHotelinfo.setPhone(phone);
//                //htChanelHotelinfo.setHotelInfo(info);
//                htChanelHotelinfo.setAxesX(longitude);
//                htChanelHotelinfo.setAxesY(latitude);
//                htChanelHotelinfo.setStatus(closeStatus);
////                htChanelHotelinfo.setPictureurl(frontImage);
//                htChanelHotelinfo.setCity(cityLocationId);

                //酒店拓展信息
                JSONObject extendInfo = htDetail.getJSONObject("extendInfo");
                //星级设施信息
                JSONObject poiExtInfo = extendInfo.getJSONObject("poiExtInfo");
                String hotelStar = poiExtInfo.getString("hotelStar");
                String poiType = poiExtInfo.getString("poiType");
                String openDateStr = poiExtInfo.getString("openDate");

                //时间值修改类型
                String decorationDateStr = poiExtInfo.getString("decorationDate");
                Date decorationDate = null;
                if (decorationDateStr != null) {
                    String decorationDateRepStr = decorationDateStr.replace("/", "-") + "-00";
                    decorationDate = ComUtil.dateStr2Date(decorationDateRepStr);
                }

                String floorNum = poiExtInfo.getString("floorNum");
                String foregiftType = poiExtInfo.getString("foregiftType");
                int typeId = 0;
                if (foregiftType != null) {
                    typeId = Integer.parseInt(foregiftType);
                }

                htHotelinfo.setDecorateTime(decorationDate);
                htHotelinfo.setFloor(floorNum);
                htHotelinfo.setChinaHotel(typeId);
                if(StringUtils.isNotBlank(poiType)){
                    htHotelinfo.setPoiType(poiType);
                }
                if(StringUtils.isNotBlank(hotelStar)){
                    htHotelinfo.setStarLevel(hotelStar);
                }

//                //渠道物理酒店
//                htChanelHotelinfo.setDecorateTime(decorationDate);
//                htChanelHotelinfo.setFloor(floorNum);
//                htChanelHotelinfo.setChinaHotel(typeId);
//                if(StringUtils.isNotBlank(hotelStar)){
//                    htChanelHotelinfo.setStarLevel(hotelStar);
//                }

                //酒店设施
//                String hotelFacilities = extendInfo.getString("hotelFacilities");

                //数据来源
                int dataFrom = 2;

                //物理酒店
                htHotelinfo.setDataFrom(dataFrom);
//                htHotelinfo.setHotelFacilities(hotelFacilities);

                //渠道物理酒店
                //htChanelHotelinfo.setService(hotelService);
//                htChanelHotelinfo.setHotelFacilities(hotelFacilities);

                //保存数据库
                htHotelinfo.setHotelFacilities(null);
//                htChanelHotelinfo.setHotelFacilities(null);

                if (!hotelList.contains(htHotelinfo)){
                    hotelList.add(htHotelinfo);
                }
//                if (!chanelHotelList.contains(htChanelHotelinfo)){
//                    chanelHotelList.add(htChanelHotelinfo);
//                }
            }
            //批量更新或插入
            htHotelinfoService.saveOrUpdateBatch(hotelList);
//            htChanelHotelinfoService.saveOrUpdateBatch(chanelHotelList);
        } else {
            message = "美团信息："+ message;
            saveErrId.saveIDList(mtCodes,taskId,message);
            return false;
        }
        return true;
    }

    /**
     * 根据酒店id查询酒店物理房型
     */
    @Override
    public boolean getHtRooms(TaskHotelList taskHotelList) {
        FxBaseApiRequest fxBaseApiRequest = new FxBaseApiRequest();
        MtClient mtClient = new MtClient();

        Long taskId = taskHotelList.getTaskId();
        List<Long> mtCodes = taskHotelList.getHotelList();
        //请求美团数据，一次查询10个酒店
        JSONObject reqData = new JSONObject();
        reqData.put("hotelIds", mtCodes);

        //请求美团数据
        fxBaseApiRequest.setData(reqData.toJSONString());


        fxBaseApiRequest.setMethod("hotel.realroom.info");
        String mtResult = "";
        try {
            mtResult = mtClient.post(fxBaseApiRequest);
        }catch (Exception ex){
            throw  new MTReqException(ex.toString());
        }
        //对美团返回数据进行解析，返回结果是json字符串，包含20个酒店的物理房型信息
        JSONObject mtResultJson = JSONObject.parseObject(mtResult);
        int code = mtResultJson.getInteger("code");
        String message = mtResultJson.getString("message");
        if (code == 0) {
            //判断数据返回是否成功，根据数据格式取出嵌套数据
            JSONObject result = mtResultJson.getJSONObject("result");
            JSONObject realRoomInfos = result.getJSONObject("realRoomInfos");
            if (realRoomInfos == null) {
                //写入数据库
                List<HtHotelinfo> hotelinfos = htHotelinfoService.getByHotelCodes(mtCodes);
                hotelinfos = hotelinfos.stream().map((item)->{
                    item.setStatus(-2);
                    return item;
                }).collect(Collectors.toList());
                htHotelinfoService.updateBatchById(hotelinfos);
                saveErrId.saveIDList(mtCodes,taskId,"美团信息：酒店下没有房型信息");
                return false;
            }

            for (Long mtCode : mtCodes) {
                //根据请求的酒店id当做key取出返回的酒店物理房型数据
                String mtCodeKey = String.valueOf(mtCode);
                JSONArray roomInfos = (JSONArray) realRoomInfos.get(mtCodeKey);

                //取出来的单个房型信息
                if(roomInfos !=null) {
                    //批量更新或插入
//                    List<HtChanelPhysicalRoom> htChanelPhysicalRooms = new ArrayList<>();
                    List<HtPhysicalRoom> htPhysicalRooms = new ArrayList<>();

                    for (Object roomInfo : roomInfos) {
                        //数据库实体类
                        HtPhysicalRoom htPhysicalRoom = new HtPhysicalRoom();
//                        HtChanelPhysicalRoom htChanelPhysicalRoom = new HtChanelPhysicalRoom();

                        Long roomCode = null; //房型id
                        JSONObject roomInfoJson = (JSONObject) JSONObject.toJSON(roomInfo);
                        JSONObject realRoomBaseInfo = roomInfoJson.getJSONObject("realRoomBaseInfo");//房型信息json
                        JSONArray goodsIds = roomInfoJson.getJSONArray("goodsIds");//商品编码json
                        JSONArray roomBedInfoList = roomInfoJson.getJSONArray("roomBedInfoList");//床型信息json
                        if (realRoomBaseInfo != null) {
                            //取出房型信息
                            roomCode = realRoomBaseInfo.getLong("realRoomId");
                            String roomName = realRoomBaseInfo.getString("roomName");
                            String capacity = realRoomBaseInfo.getString("capacity");
                            String useableArea = realRoomBaseInfo.getString("useableArea");
                            String floor = realRoomBaseInfo.getString("floor");
                            //String roomDesc = realRoomBaseInfo.getString("roomDesc");
                            String windowView = realRoomBaseInfo.getString("windowView");
                            String internetWay = realRoomBaseInfo.getString("internetWay");
                            int window = realRoomBaseInfo.getInteger("window");
                            String windowBad = realRoomBaseInfo.getString("windowBad");
                            int extraBed = realRoomBaseInfo.getInteger("extraBed");
                            int status = realRoomBaseInfo.getInteger("status");
                            String childCapacity = realRoomBaseInfo.getString("childCapacity");
                            //床型信息
                            if (roomBedInfoList != null) {
                                List roomBedInfos = (List) roomBedInfoList.get(0);//取出床型信息
                                String bedType = "";
                                if(roomName.contains("双人") || roomName.contains("双床")){
                                    bedType = "双床";
                                }else {
                                    JSONObject roomBedInfo = (JSONObject) roomBedInfos.get(0);
                                    bedType = roomBedInfo.getString("bedType");
                                }
                                if (roomName.contains("标准房 ") || roomName.contains("标准间")){
                                    bedType = "";
                                }
                                //String bedDesc = roomBedInfo.getString("bedDesc");
                                htPhysicalRoom.setBedPad(bedType);//设置物理房型实体类
                                //htPhysicalRoom.setBedWidth(bedDesc);

                                //设置渠道物理房型实体类
//                                htChanelPhysicalRoom.setBedPad(bedType);
                                //htChanelPhysicalRoom.setBedWidth(bedDesc);
                            }

                            //设置物理房型实体类
                            Long mtCodeLong = Long.parseLong(mtCodeKey);
                            htPhysicalRoom.setHotelCode(mtCodeLong);
                            htPhysicalRoom.setRoomCode(roomCode);
                            htPhysicalRoom.setId(roomCode);
                            htPhysicalRoom.setRoomName(roomName);
                            htPhysicalRoom.setMaxNum(capacity);
                            htPhysicalRoom.setRoomSize(useableArea);
                            htPhysicalRoom.setRoomFloor(floor);
                            //htPhysicalRoom.setRoomContent(roomDesc);
                            htPhysicalRoom.setWindows(window);
                            htPhysicalRoom.setWindowInfo(windowView);
                            htPhysicalRoom.setInternet("A");
                            htPhysicalRoom.setWindowBad(windowBad);
                            htPhysicalRoom.setUpBed(extraBed);
                            htPhysicalRoom.setRoomStatus(status);
                            htPhysicalRoom.setMaxChild(childCapacity);
                            htPhysicalRoom.setDataFrom(2);

//                            //设置渠道物理房型实体类
//                            htChanelPhysicalRoom.setChanelCode(2);
//                            htChanelPhysicalRoom.setId(roomCode);
//                            htChanelPhysicalRoom.setChanelRoomCode(roomCode);
//                            htChanelPhysicalRoom.setRoomCode(roomCode);
//                            htChanelPhysicalRoom.setRoomName(roomName);
//                            htChanelPhysicalRoom.setMaxNum(capacity);
//                            htChanelPhysicalRoom.setRoomSize(useableArea);
//                            htChanelPhysicalRoom.setRoomFloor(floor);
//                            //htChanelPhysicalRoom.setRoomContent(roomDesc);
//                            htChanelPhysicalRoom.setWindows(window);
//                            htChanelPhysicalRoom.setWindowInfo(windowView);
//                            htChanelPhysicalRoom.setInternet("A");
//                            htChanelPhysicalRoom.setWindowBad(windowBad);
//                            htChanelPhysicalRoom.setUpBed(extraBed);
//                            htChanelPhysicalRoom.setRoomStatus(status);
//                            htChanelPhysicalRoom.setMaxChild(childCapacity);
                        }

                        //批量更新插入列表
                        htPhysicalRooms.add(htPhysicalRoom);
//                        htChanelPhysicalRooms.add(htChanelPhysicalRoom);

                        //提取物理房型的产品id
                        if (goodsIds != null) {
                            List<HtLogicRoom> htLogicRooms = new ArrayList<>();
                            List<Long> htLogicRoomsId = new ArrayList<>();
                            for (Object goodsId : goodsIds) {
                                HtLogicRoom htLogicRoom = new HtLogicRoom();
                                String goodsIdSte = String.valueOf(goodsId);
                                Long rpId = Long.parseLong(goodsIdSte);
                                htLogicRoom.setId(rpId);
                                htLogicRoom.setHotelCode(mtCode);
                                htLogicRoom.setRoomCode(roomCode);
                                htLogicRoom.setRpCode(rpId);
                                if (!htLogicRoomsId.contains(rpId)){
                                    htLogicRooms.add(htLogicRoom);
                                    htLogicRoomsId.add(rpId);
                                }
                            }
                            htLogicRoomService.saveOrUpdateBatch(htLogicRooms);
                        }
                    }
                    //批量插入或更新
//                    htChanelPhysicalRoomService.saveOrUpdateBatch(htChanelPhysicalRooms);
                    htPhysicalRoomService.saveOrUpdateBatch(htPhysicalRooms);
                }
            }
        }else {
            //保存错误的酒店id
            saveErrId.saveIDList(mtCodes,taskId,message);
            return false;
        }
        return true;
    }

    /**
     * 逻辑房型信息及房态
     */
    @Override
    public void getGoods(TaskHotelList taskHotelList) {
        FxBaseApiRequest fxBaseApiRequest = new FxBaseApiRequest();
        MtClient mtClient = new MtClient();

        Long taskId = taskHotelList.getTaskId();
        List<Long> mtCodes = taskHotelList.getHotelList();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date today = new Date();
        String startDate = sdf.format(today); //当前日期
        Calendar theCa = Calendar.getInstance();
        theCa.setTime(today);
        theCa.add(Calendar.DATE, 30); //最后一个数字30可改，30天的意思
        Date start = theCa.getTime();
        String endDate = sdf.format(start); //三十天之前日期

        JSONObject reqData = new JSONObject();
        reqData.put("hotelIds", mtCodes);
        reqData.put("checkinDate", startDate);
        reqData.put("checkoutDate", endDate);
        reqData.put("goodsType", 1);

        //请求美团数据
        fxBaseApiRequest.setData(reqData.toJSONString());
        fxBaseApiRequest.setMethod("hotel.goods.rp");
        String mtResult = "";
        try {
            mtResult = mtClient.post(fxBaseApiRequest);
        }catch (Exception ex){
            throw  new MTReqException(ex.toString());
        }
        //对美团返回数据进行解析，返回结果是json字符串，包含20个酒店的物理房型信息
        JSONObject mtResultJson = JSONObject.parseObject(mtResult);
        String message = mtResultJson.getString("message");
        int code = mtResultJson.getInteger("code");
        if (code == 0) {
            JSONObject htResult = mtResultJson.getJSONObject("result");
            JSONArray htGoodsList = htResult.getJSONArray("hotelGoods");
            if (htGoodsList != null) {
                for (Object goodsList : htGoodsList) {
                    JSONObject goodsJson = (JSONObject) JSONObject.toJSON(goodsList);
                    JSONArray goodsListJson = goodsJson.getJSONArray("goods");
                    Long hotelCode = goodsJson.getLong("hotelId");
                    HashMap<String, List> htDailyroomsMap = new HashMap<String, List>();

                    List<HtLogicRoom> htLogicRooms = new ArrayList<>();
                    List<Long> htLogicRoomIds = new ArrayList<>();
                    for (Object goods : goodsListJson) {

                        HtLogicRoom htLogicRoom = new HtLogicRoom();
                        JSONObject jsonRP = (JSONObject) JSONObject.toJSON(goods);
                        int goodsStatus = jsonRP.getInteger("goodsStatus");
                        String goodsName = jsonRP.getString("goodsName");
                        Integer goodsType = jsonRP.getInteger("goodsType");
                        // 如果是房态：0 满房 1 可预订 2 不可预订 3 不展示
                        if(goodsStatus > 1 || StringUtils.isBlank(goodsName) || goodsType == null ){
                            continue;
                        }
                        Long rpCode = jsonRP.getLong("goodsId");
                        int confirmType = jsonRP.getInteger("confirmType");
                        int averagePrice = jsonRP.getInteger("averagePrice");
                        int originalPrice = jsonRP.getInteger("originalPrice");
                        int thirdParty = jsonRP.getInteger("thirdParty");
                        int paymentTypeInt = jsonRP.getInteger("paymentType");
                        int paymentType;
                        if (paymentTypeInt == 0) {
                            paymentType = 1;
                        } else {
                            paymentType = paymentTypeInt;
                        }

                        htLogicRoom.setHotelCode(hotelCode);  // set酒店编码
                        htLogicRoom.setRpCode(rpCode);   // set rp编码
                        htLogicRoom.setId(rpCode);
                        /**房态：
                         0 满房
                         1 可预订
                         2 不可预订
                         3 不展示*/
                        htLogicRoom.setStatus(goodsStatus);
                        htLogicRoom.setRpName(goodsName); //价格计划名称

                        /**产品类型：
                         1 全日房
                         2 钟点房*/
                        htLogicRoom.setType(goodsType);
                        /**确认类型：
                         0 不支持即时确认
                         1 支持即时确认*/
                        htLogicRoom.setVerifyType(String.valueOf(confirmType));
                        htLogicRoom.setAvgPrice(averagePrice);
                        htLogicRoom.setMarketPrice(originalPrice);
                        /**是否第三方产品。
                         0 非第三方
                         1 第三方*/
                        htLogicRoom.setIsThree(thirdParty);
                        /**支付方式 0：预付，2：现付非担保*/
                        htLogicRoom.setPaymentType(paymentType);

                        List breakfastList = jsonRP.getJSONArray("breakfast"); // 早餐list
                        //List roomInfoList = jsonRP.getJSONArray("roomInfoList"); //
                        //JSONObject roomInfo = (JSONObject) roomInfoList.get(0);
                        //String roomCode = roomInfo.getString("roomId");
                        //htLogicRoom.setRoomCode(roomCode); // set房型编码

                        List cancelRules = jsonRP.getJSONArray("cancelRules"); // 取消规则list
                        JSONArray bookRules = jsonRP.getJSONArray("bookRules");     // 预定规则list
                        Long goodsId = jsonRP.getLong("goodsId");          // 价格政策id

                        // 价格政策
                        if (!bookRules.isEmpty()) {
                            JSONObject bookRuleJson = (JSONObject) bookRules.get(0);

                            // 连住天数（预定政策）
                            int serialCheckinMin = bookRuleJson.getInteger("serialCheckinMin");
                            int serialCheckinMax = bookRuleJson.getInteger("serialCheckinMax");
                            if (serialCheckinMin == 0) {
                                serialCheckinMin = 1;
                            }
                            if (serialCheckinMax == 0) {
                                serialCheckinMax = 90;
                            }

                            htLogicRoom.setMinDays(serialCheckinMin);
                            htLogicRoom.setMaxDays(serialCheckinMax);
                            // 最早预定时间数
                            int earlyNum = 30;// 初始设置最大时间30天
                            String earliestBookingDays = bookRuleJson.getString("earliestBookingDays");
                            if (earliestBookingDays != null & !"0".equals(earliestBookingDays) & !"-1".equals(earliestBookingDays)) {
                                earlyNum = Integer.parseInt(earliestBookingDays);
                            }
                            int earlyHours;
                            String earliestBookingHours = bookRuleJson.getString("earliestBookingHours");
                            int earlyAllHours;
                            if (earliestBookingHours != null) {
                                earlyHours = ComUtil.time2Hour(earliestBookingHours); // 凌晨向前的小时量
                                earlyAllHours = (earlyNum - 1) * 24 + earlyHours;
                            } else {
                                earlyAllHours = earlyNum * 24;
                            }
                            htLogicRoom.setMaxHours(earlyAllHours);

                            // 最晚预定时间数
                            int latestNum = 0;// 初始设置最大时间30天
                            String latestBookingDays = bookRuleJson.getString("latestBookingDays");
                            if (latestBookingDays != null & !"0".equals(latestBookingDays) & !"-1".equals(latestBookingDays)) {
                                latestNum = Integer.parseInt(latestBookingDays);
                            }
                            int latestHours;
                            String latestBookingHours = bookRuleJson.getString("latestBookingHours");
                            int isDaybreakBooking = bookRuleJson.getInteger("isDaybreakBooking");

                            int latestAllHours;
                            if (latestBookingHours != null) {
                                latestHours = ComUtil.time2Hour(latestBookingHours); // 凌晨向前的小时量
                                latestAllHours = latestNum * 24 + latestHours;

                            } else {
                                latestAllHours = latestNum * 24;
                            }
                            if (isDaybreakBooking == 1) {
                                latestAllHours = 0;
                            }

                            htLogicRoom.setMinHours(latestAllHours);
                        }
                        // 早餐规则
                        if (breakfastList != null) {
                            for (Object breakfast : breakfastList) {
                                JSONArray breakfastCals = new JSONArray(); // 某天的早餐规则
                                JSONObject breakfastJson = (JSONObject) JSONObject.toJSON(breakfast);

                                int breakfastNum = 0;
                                int breakfastType = breakfastJson.getInteger("breakfastType");
                                if (breakfastType == 1) {
                                    breakfastNum = breakfastJson.getInteger("breakfastNum");
                                }
                                int inStartDate = breakfastJson.getInteger("inStartDate");
                                int inEndDate = breakfastJson.getInteger("inEndDate");
                                if (inStartDate == 0 & inEndDate == 0) {
                                    htLogicRoom.setBreakfastNum(breakfastNum);
                                } else {
                                    BreakfastCal breakfastCal = new BreakfastCal();
                                    String startDateInt = ComUtil.intDate2String(inStartDate);
                                    String endDateInt = ComUtil.intDate2String(inEndDate);
                                    breakfastCal.setBreakfast_count(breakfastNum);
//                                    breakfastCal.setDate("");
                                    breakfastCal.setStartDate(startDateInt);
                                    breakfastCal.setEndDate(endDateInt);
                                    String breakfastCalString = JSON.toJSONString(breakfastCal);
                                    JSONObject breakfastCalJson = (JSONObject) JSONObject.parse(breakfastCalString);
                                    breakfastCals.add(breakfastCalJson);
                                }
                                if (!breakfastCals.isEmpty()) {
                                    htLogicRoom.setBreakfastCal(breakfastCals.toJSONString());
                                }
                            }
                        }
                        // 取消规则
                        if (cancelRules != null) {
                            JSONObject cancel_policy = new JSONObject();
                            JSONObject cancelRuleJson = (JSONObject) cancelRules.get(0);
                            int cancelType = cancelRuleJson.getInteger("cancelType");
                            if (cancelType == 0) {
                                cancel_policy.put("cancelPolicyType", 2);
                            } else {
                                cancel_policy.put("cancelPolicyType", 5);
                                JSONObject policyInfo = new JSONObject();
                                // 可取消
                                int aheadCancelDays = cancelRuleJson.getInteger("aheadCancelDays"); // 提前取消天数 0表示当天
                                int aheadHour = aheadCancelDays * 24; // 天数转换为小时
                                int allHour = 0;  // 总时间量
                                int deductType = cancelRuleJson.getInteger("deductType");  // 提前取消类型
                                if (deductType == 0) {
                                    // 提前取消时间
                                    String aheadCancelHours = cancelRuleJson.getString("aheadCancelHours");
                                    int hour = ComUtil.time2Hour(aheadCancelHours);
                                    allHour = aheadHour + hour;  // 总时间
                                    if (allHour==0){
                                        allHour=1;
                                    }
                                    policyInfo.put("timeBefore", allHour);
                                } else {
                                    // 提前取消时间量
                                    int aheadCancelHours = cancelRuleJson.getInteger("aheadCancelHours");
                                    allHour = aheadHour + aheadCancelHours; // 总时间
                                    if (allHour==0){
                                        allHour=1;
                                    }
                                    policyInfo.put("timeBefore", allHour);
                                }
                                cancel_policy.put("policyInfo", policyInfo);
                            }
                            htLogicRoom.setCancelPolicy(cancel_policy.toJSONString());
                        }

                        List priceModels = jsonRP.getJSONArray("priceModels");
                        List<HtDailyroom> htDailyrooms = new ArrayList<>();
                        List<Long> htRpCodes = new ArrayList<>();
                        //如果没有价格，造一个价格
                        if(priceModels.isEmpty()){
                            priceModels.add("{'date':"+ DateUtils.format(new Date(),"yyyy-MM-dd") + ",'salePrice':0,'dayType':0,'subRatio':0,'subPrice':0}");
                        }
                        for (Object priceModel : priceModels) {
                            JSONObject jsonPriceModel = (JSONObject) JSONObject.toJSON(priceModel);
                            String dateString = jsonPriceModel.getString("date");
                            Date date = ComUtil.dateStr2Date(dateString);
                            int price = jsonPriceModel.getInteger("salePrice");

                            HtDailyroom htDailyroom = new HtDailyroom();
                            Long rpId = new Long((goodsId + ComUtil.dateStr2Integer(dateString)));
                            htDailyroom.setId(rpId);
                            htDailyroom.setRpCode(goodsId);
                            htDailyroom.setPriceDate(date);
                            htDailyroom.setPrice(price);
//                            if (!htRpCodes.contains(goodsId)){
//                                htRpCodes.add(goodsId);
                            htDailyrooms.add(htDailyroom);
//                            }

                        }
                        String goodsIdStr = String.valueOf(goodsId);
                        htDailyroomsMap.put(goodsIdStr, htDailyrooms);
                        if (!htLogicRoomIds.contains(rpCode)){
                            htLogicRoomIds.add(rpCode);
                            htLogicRooms.add(htLogicRoom);
                        }
                    }
                    htLogicRoomService.updateBatchById(htLogicRooms);

                    boolean goodStatus = reqGoodStatus(hotelCode, startDate, endDate, htDailyroomsMap,taskId);
                    if (!goodStatus) {
                        //这里要将错误酒店id存入数据库
                        List<Long> mtCodeList = new ArrayList<>();
                        mtCodes.add(hotelCode);
//                        saveErrId.saveIDList(mtCodeList,taskId,"房态库存更新错误");
//                        log.error("酒店信息获取完毕,房态库存更新错误_"+hotelCode);
                    }
                }
            }else {
//                saveErrId.saveIDList(mtCodes,taskId,"获取酒店商品数据为空");
//                log.info("酒店房态信息返回为空_"+mtCodes);
            }
        } else {
            saveErrId.saveIDList(mtCodes,taskId,message);
        }
        htLogicRoomService.sqlDel(mtCodes);
    }

    /**获取酒店实时房态*/
    private boolean reqGoodStatus(Long hotelId, String checkinDate, String checkoutDate, Map htDailyroomsMap,Long taskId) {
        FxBaseApiRequest fxBaseApiRequest = new FxBaseApiRequest();
        MtClient mtClient = new MtClient();
//        log.info("获取酒店房态_"+hotelId);
        /**库存数据*/
        JSONObject reqData = new JSONObject();
        reqData.put("hotelId", hotelId);
        reqData.put("checkinDate", checkinDate);
        reqData.put("checkoutDate", checkoutDate);
        reqData.put("goodsType", 1);
        fxBaseApiRequest.setData(reqData.toJSONString());
        fxBaseApiRequest.setMethod("hotel.goods.status");
        String mtResult = mtClient.post(fxBaseApiRequest);
        JSONObject mtResultJson = JSONObject.parseObject(mtResult);
        int code = mtResultJson.getInteger("code");
        String message = mtResultJson.getString("message");
        if (code == 0) {
            JSONObject resultJson = mtResultJson.getJSONObject("result");
            JSONArray goodsStatuses = resultJson.getJSONArray("goodsStatuses");
            for (Object goodsStatus : goodsStatuses) {
                JSONObject goodsStatusJson = (JSONObject) JSONObject.toJSON(goodsStatus);
                Long goodsId = goodsStatusJson.getLong("goodsId");
                String goodsIdStr =  String.valueOf(goodsId);
                List htDailyroomPrices = (List) htDailyroomsMap.get(goodsIdStr);
                List<HtDailyroom> htDailyroomPricesList = new ArrayList<>();
                if (htDailyroomPrices==null) {
                    /**价格数据没有时，发起请求*/
                    JSONObject reqPriceData = new JSONObject();
                    List<Long> goodsIds = new ArrayList<>();
                    goodsIds.add(goodsId);
                    reqPriceData.put("goodsIds", goodsIds);
                    reqPriceData.put("startDate", checkinDate);
                    reqPriceData.put("endDate", checkoutDate);
                    fxBaseApiRequest.setData(reqPriceData.toJSONString());
                    fxBaseApiRequest.setMethod("hotel.goods.price");
                    String mtResultPrice = mtClient.post(fxBaseApiRequest);
                    JSONObject mtResultPriceJson = JSONObject.parseObject(mtResultPrice);
                    int mtResultPriceJsonCode = mtResultPriceJson.getInteger("code");
                    String mtResultPriceJsonMessage = mtResultPriceJson.getString("message");
                    if (mtResultPriceJsonCode == 0) {
                        JSONObject priceResultJson = mtResultPriceJson.getJSONObject("result");
                        JSONArray goodsPrices = priceResultJson.getJSONArray("goodsPrices");
                        if (goodsPrices==null||goodsPrices.isEmpty()) {
                            continue;
                        }
                        JSONObject priceModelObject = goodsPrices.getJSONObject(0);
                        JSONArray priceModels = priceModelObject.getJSONArray("priceModels");

                        for (Object priceModel : priceModels) {
                            HtDailyroom htDailyroomPrice = new HtDailyroom();
                            JSONObject priceModelJson = (JSONObject) JSONObject.toJSON(priceModel);
                            String dates = priceModelJson.getString("date");
                            int salePrice = priceModelJson.getInteger("salePrice");
                            java.sql.Date date = (java.sql.Date) ComUtil.dateStr2Date(dates);
                            Long id = new Long((goodsId + ComUtil.dateStr2Integer(dates)));
                            htDailyroomPrice.setId(id);
                            htDailyroomPrice.setRpCode(goodsId);
                            htDailyroomPrice.setPriceDate(date);
                            htDailyroomPrice.setPrice(salePrice);
                            htDailyroomPricesList.add(htDailyroomPrice);
                        }
                    } else {
                        List<Long> mtCodes = new ArrayList<>();
                        mtCodes.add(hotelId);
                        saveErrId.saveIDList(mtCodes,taskId,mtResultPriceJsonMessage);
                        return false;
                    }
                }

                //[{"date":"2020-10-16","status":0}......]数据格式
                JSONArray statusList = goodsStatusJson.getJSONArray("goodsStatuses");
                List<HtDailyroom> htDailyRooms = new ArrayList<>();
                List<Long> htDailyRoomIds = new ArrayList<>();
//                int sizeNum;
                List htDailyRoomPricesLists;
                if (htDailyroomPrices != null) {
//                    sizeNum = htDailyroomPrices.size();
                    htDailyRoomPricesLists = htDailyroomPrices;
                } else {
//                    sizeNum = htDailyroomPricesList.size();
                    htDailyRoomPricesLists = htDailyroomPricesList;
                }
                HashMap<String,HtDailyroom> htDailyRoomPriceMap = new HashMap<>();
                for (Object priceHtDailyRoom:htDailyRoomPricesLists) {
                    HtDailyroom priceHtDailyRoomDto = JSONObject.parseObject(JSON.toJSONString(priceHtDailyRoom),HtDailyroom.class);
                    htDailyRoomPriceMap.put(String.valueOf(priceHtDailyRoomDto.getId()),priceHtDailyRoomDto);
                }

                for (Object statusOb : statusList) {

//                    int index = statusList.indexOf(statusOb);
                    HtDailyroom htDailyroom = new HtDailyroom();
                    htDailyroom.setRpCode(goodsId);
                    //价格列表长度超过当前房态索引，根据房态索引取出价格数据
//                    if (sizeNum > index) {
//                        HtDailyroom htDailyRoomJson = (HtDailyroom) htDailyRoomPricesLists.get(index);
//                        if (htDailyroom.getRpCode().equals(htDailyRoomJson.getRpCode())) {
//                            htDailyroom.setPrice(htDailyRoomJson.getPrice());
//                        }
//                    }
                    JSONObject statusJson = (JSONObject) JSONObject.toJSON(statusOb);
                    String dates = statusJson.getString("date");
                    Long id = new Long((goodsId + ComUtil.dateStr2Integer(dates)));
                    HtDailyroom htDailyRoomJson =  htDailyRoomPriceMap.get(String.valueOf(id));
                    if (htDailyRoomJson == null){
                        continue;
                    }
                    htDailyroom.setPrice(htDailyRoomJson.getPrice());
                    java.sql.Date date = (java.sql.Date) ComUtil.dateStr2Date(dates);
                    int status = statusJson.getInteger("status");
                    int roomCount;
                    if (status == 1){
                        roomCount = 2;
                    }else {
                        roomCount = 0;
                    }
                    htDailyroom.setId(id);
                    htDailyroom.setPriceDate(date);
                    htDailyroom.setSaleNum(roomCount);
                    if (!htDailyRoomIds.contains(id)){
                        htDailyRoomIds.add(id);
                    htDailyRooms.add(htDailyroom);
                    }
                }
                htDailyroomService.saveOrUpdateBatch(htDailyRooms);
            }
        } else {
//            log.info("获取酒店房态发生未知错误——"+hotelId+message);
            List<Long> mtCodes = new ArrayList<>();
            mtCodes.add(hotelId);
            saveErrId.saveIDList(mtCodes,taskId,message);
            return false;
        }
        return true;
    }
}



